import stat, os, shutil, time, platform
from typing import List

import svn, svn.remote

import Util
from Logger import Logger



def checkoutSvnDir(logger: Logger, localBaseDir, svnBaseUrl, svnUsername, svnPassword):
    """checkout svn 文件"""
    # 创建目录
    Util.tryCreateDirectory(localBaseDir)
    # 在svn上创建子目录，如果子目录不存在
    print("svnBaseUrl" + svnBaseUrl)
    svnUrl = svnBaseUrl.replace(' ', '%20')
    print("svnUrl:" + svnUrl)
    logger.logNotice("[SVN][Checkout]  开始检出svn资源，地址:" + svnUrl)
    try:
        # 将目录checkout下来
        svnClient = svn.remote.RemoteClient(svnUrl, username=svnUsername, password=svnPassword)
        svnClient.checkout(localBaseDir)
    except Exception as e:
        logger.logError("[SVN][Checkout]  开始检出svn资源失败！！ 地址:" + localBaseDir)
        logger.logError(str(e))
        for arg in e.args:
            logger.logError(str(arg))
    logger.logNotice("[SVN][Checkout]  检出svn资源完毕，地址:" + svnUrl)
    return True


class CommitDate:
    files:List[str]
    genCodePath: str
    svnPath: str


def commitSVNFiles(logger: Logger, localBaseDir, svnUrl, files:List[str], svnUsername, svnPassword):
    """执行提交操作"""

    # 提交SVN
    svnUrl = svnUrl.replace(' ', '%20')
    svnClient = svn.remote.RemoteClient(svnUrl, username=svnUsername, password=svnPassword)

    for targetLocalfilePath in files:

        # 如果本地文件不存在，就不用提交了
        if not Util.isFileAndExists(targetLocalfilePath):
            logger.logError('[SVN][Commit]  要向SVN仓库提交的本地文件不存在')
            continue

        fileName = os.path.split(targetLocalfilePath)[-1]
        logger.logSuccess("[SVN][Commit] 开始提交文件：" + fileName)
        try:
            # 先执行add操作
            svnSubCommandAdd = 'add'
            commandArgsAdd = ["--force", targetLocalfilePath]
            svnClient.run_command(svnSubCommandAdd, commandArgsAdd)
        except Exception as e:
            logger.logError("[SVN][Commit] 添加文件：" + fileName + " 失败！！！")
            for arg in e.args:
                logger.logError(str(arg))

    try:
        # 再执行commit操作
        svnSubCommandCommit = 'commit'
        #commandArgsCommit = [targetLocalfilePath, '-m', 'Excel2Json程序提交文件：' + fileName]
        commandArgsCommit = [localBaseDir, '-m', 'Excel2Json']
        svnClient.run_command(svnSubCommandCommit, commandArgsCommit)
    except Exception as e:
        logger.logError("[SVN][Commit] 提交文件：" + svnUrl + " 失败！！！")
        for arg in e.args:
            logger.logError(str(arg))
        return False

    logger.logSuccess("[SVN][Commit] 提交文件：" + svnUrl + " 完成！！！")
    return True


def svnMkdir(logger: Logger, svnBaseUrl:str, svnUsername:str, svnPassword:str):
    svnClient = svn.remote.RemoteClient(svnBaseUrl, username=svnUsername, password=svnPassword)
    # 执行创建SVN 子目录的命令
    subDir:str = svnBaseUrl.split("/")[-1]
    svn_sub_command = 'mkdir'
    command_args = ["--parents", "-m", "python程序创建svn目录：" + subDir,
                    str(svnBaseUrl).replace(' ', '%20')]
    try:
        svnClient.run_command(svn_sub_command, command_args)
    except:
        # logger.logError("[SVN][Mkdir] 创建SVN文件夹失败:" + subDir)
        return False
    logger.logSuccess("[SVN][Mkdir] 创建SVN文件夹:" + subDir)
    return True

def svnDelete(logger: Logger, svnBaseUrl:str, svnFullPath:str, svnUsername:str, svnPassword:str):
    """
    删除一个svn上的目录或文件
    :param logger: 日志
    :param svnBaseUrl: svn登陆地址
    :param svnFullPath: 需要删除的目录或文件名的全svn地址，如：svn://xxx/svn/data/a.txt
    :param svnUsername: svn账号
    :param svnPassword: svn密码
    :return:
    """
    svnClient = svn.remote.RemoteClient(svnBaseUrl, username=svnUsername, password=svnPassword)
    svn_sub_command = 'delete'
    deletePath:str = Util.fixUrlBackslash(svnBaseUrl + svnFullPath, False)
    command_args = ["-m", "python程序删除文件夹：" + svnFullPath,
                    str(deletePath).replace(' ', '%20')]
    try:
        svnClient.run_command(svn_sub_command, command_args)
        logger.logSuccess("[SVN][delete] 删除SVN文件夹:" + svnFullPath)
    except Exception as e:
        print(e)
        logger.logError("[SVN][delete] 删除失败！！ SVN文件(夹):" + svnFullPath)
        return False

    return True

#
# def deleteDirsRecursion(dirPath):
#     """递归删除"""
#     # if not isDirAndExists(dirPath):
#     if not os.path.exists(dirPath):
#         return
#     if platform.system().lower() == 'windows':
#         shutil.rmtree(dirPath, onerror=remove_readonly)
#     else:
#         shutil.rmtree(dirPath)
#
#
# def remove_readonly(func, path, _):
#     """解决： shutil.rmtree 在Windows 上删除只读文件报错问题"""
#     os.chmod(path, stat.S_IWRITE)
#     func(path)
